using System;
using FireStarterModeller.BO;
using Habanero.Base;
using Habanero.BO;
using Habanero.Faces.Base;
using Habanero.Faces.Win;
using DockStyle=System.Windows.Forms.DockStyle;

namespace FireStarterModeller.UI
{
    /// <summary>
    /// This control is used for selecting a particular class for a particular assembly give the solution.
    /// </summary>
    public class DMSolutionControl : UserControlWin, IFormControl, IBOParentChildrenSelector
    {
        private IControlFactory ControlFactory { get; set; }
        private readonly DMClassGridSelectorControl _dmClassGridSelectorControl;

        private DMSolution _dmSolution;

        public EventHandler DeleteClicked;
        public EventHandler<BOEventArgs> CancelClicked;
        private DMClass _dmClass;
        private readonly EventHandler<BOEventArgs> _grid_OnSelectedHandler;


        public event EventHandler<BOEventArgs> BusinessObjectSelected;


        public DMSolutionControl(IControlFactory controlFactory)
        {
            ControlFactory = controlFactory;
            if (controlFactory == null) throw new ArgumentNullException("controlFactory");

            BorderLayoutManager mainLayoutManager = controlFactory.CreateBorderLayoutManager(this);
            _dmClassGridSelectorControl = new DMClassGridSelectorControl(controlFactory);
            _grid_OnSelectedHandler = ClassGridSelectorControl_OnBusinessObjectSelected;
            IPanel panel = SetUpSelectorPanel(controlFactory);
            mainLayoutManager.AddControl(panel, BorderLayoutManager.Position.Centre);
            this.Enabled = false;
        }

        private void ClassGridSelectorControl_OnBusinessObjectSelected(object sender, BOEventArgs e)
        {
            try
            {
                DMClass dmClass = (DMClass)e.BusinessObject;
                FireClassSelected(dmClass);
            }
            catch (Exception ex)
            {
                GlobalRegistry.UIExceptionNotifier.Notify(ex, "", "Error ");
            }

        }

        ~DMSolutionControl()
        {
            _dmClassGridSelectorControl.BusinessObjectSelected -= _grid_OnSelectedHandler;
        }

        private IPanel SetUpSelectorPanel(IControlFactory controlFactory)
        {
            IPanel panel = controlFactory.CreatePanel();
            IButtonGroupControl buttonGroupControl = controlFactory.CreateButtonGroupControl();
            //buttonGroupControl.AddButton("Cancel", "&Cancel", (sender, e) => CancelEditsToSolution());
            buttonGroupControl.AddButton("Delete", "&Delete", DeleteClass_ClickHandler);
            buttonGroupControl.AddButton("New", "&New", (sender,e) => CreateNewClass());
            panel.Controls.Add(_dmClassGridSelectorControl);

            // Handle the swaping of code from visible to not visible
            panel.Controls.Add(buttonGroupControl);
            _dmClassGridSelectorControl.Dock = DockStyle.Fill;
            buttonGroupControl.Dock = Habanero.Faces.Base.DockStyle.Bottom;
            _dmClassGridSelectorControl.Visible = true;
            _dmClassGridSelectorControl.BusinessObjectSelected += _grid_OnSelectedHandler;
            return panel;
        }

        private void DeleteClass_ClickHandler(object sender, EventArgs e)
        {
            if (this.DeleteClicked !=null)
            {
                this.DeleteClicked(this, new EventArgs());
            }

            if (_dmClassGridSelectorControl.BusinessObjectCollection.Count == 0)
            {
                SelectClass(null);
            }
        }
        
        //private void CancelEditsToSolution()
        //{
        //    try
        //    {
        //        this.Solution.CancelCreatedProperties();
        //        //Hack: This is a massive Hack but did not have time to track this down
        //        // Somehow there is something that is catching the restored event for a DMClass and setting the AssemblyID to null.
        //        // We could not find exacty which event. The DMClass is still seen as dirty because its assemblyID has been set to null but it is so the 
        //        // second CancelCreatedProperties restores the values back to the Persisted Value.
        //        this.Solution.CancelCreatedProperties();
        //        if (this.CancelClicked != null)
        //        {
        //            this.CancelClicked(this, new BOEventArgs(_dmClass));
        //            if (_dmClass == null) return;
        //            DMAssembly dmAssembly = _dmClass.Assembly;
        //            if (dmAssembly == null) return;
        //        }

        //    }
        //    catch (Exception ex)
        //    {
        //        GlobalRegistry.UIExceptionNotifier.Notify(ex, "", "Error ");
        //    }
        //}

        public void CreateNewClass()
        {
            try
            {
                if (this.Solution == null) return;
                if (this.Solution.DefaultAssembly == null)
                {
                    if (this.Solution.Assemblies.Count <= 0) return;
                    this.Solution.DefaultAssembly = this.Solution.Assemblies[0];
                }
                BusinessObjectCollection<DMClass> classes = this.Solution.DefaultAssembly.Classes;
                DMClass newDMClass = classes.CreateBusinessObject();
                IDefaultBOEditorForm defaultBOEditorForm = GetDefaultBOEditorForm(newDMClass);
                defaultBOEditorForm.Closed += delegate
                    {
                        if (newDMClass.Status.IsNew)
                        {
                            //classes.Remove(newDMClass);
                            newDMClass.MarkForDelete();
                            newDMClass.Save();

                        } else
                        {
                            newDMClass.CreateObjectIdWithDefaultProp();
                        }
                    };
                ShowDMClassForm(defaultBOEditorForm);
/*                //This is a Hack to force the Assemblies classes to load this somehow causes the treeview to work
                if (newDMClass != null)
                {
                    if (newDMClass.Assembly != null)
                    {
                        BusinessObjectCollection<DMClass> classes1 = newDMClass.Assembly.Classes;
                    }
                    SelectClass(newDMClass);
                }*/
            }
            catch (Exception ex)
            {
                GlobalRegistry.UIExceptionNotifier.Notify(ex, "", "Error ");
            }
        }

        public virtual void ShowDMClassForm(IDefaultBOEditorForm defaultBOEditorForm)
        {
            defaultBOEditorForm.ShowDialog();
        }

        public void SelectClass(DMClass newDMClass)
        {
            _dmClassGridSelectorControl.SelectedBusinessObject = newDMClass;
            _dmClass = newDMClass;
        }

        public IDefaultBOEditorForm GetDefaultBOEditorForm(DMClass newDMClass)
        {
            IDefaultBOEditorForm defaultBOEditorForm = this.ControlFactory.CreateBOEditorForm(newDMClass, "default");
            IPanelInfo panelInfo = defaultBOEditorForm.PanelInfo;
            RelationshipComboBoxMapper controlMapper = (RelationshipComboBoxMapper)panelInfo.FieldInfos["Assembly"].ControlMapper;
            controlMapper.BusinessObjectCollection = this.Solution.Assemblies;
            controlMapper.Control.TabIndex = 8;
            return defaultBOEditorForm;
        }

        private void FireClassSelected(DMClass dmClass)
        {
            _dmClass = dmClass;
            if (this.BusinessObjectSelected == null) return;
            this.BusinessObjectSelected(this, new BOEventArgs(dmClass));
        }

        public DMClass DMClass
        {
            get { return _dmClass; }
        }

        public DMSolution Solution
        {
            get { return _dmSolution; }
            set
            {
                _dmSolution = value;
                if (_dmSolution != null)
                {
                    this.Enabled = true;
                    DMClassGridSelectorControl.Solution  = _dmSolution;
                }
                else
                {
                    this.Enabled = false;
                }
            }
        }

        public IBusinessObject BusinessObject
        {
            get { return this.Solution; }
            set { this.Solution = (DMSolution)value;
            if (_dmClassGridSelectorControl.SelectedBusinessObject != null) FireClassSelected((DMClass) _dmClassGridSelectorControl.SelectedBusinessObject);

            }
        }


        public DMClassGridSelectorControl DMClassGridSelectorControl
        {
            get { return _dmClassGridSelectorControl; }
        }

        #region Implementation of IFormControl

        public void SetForm(IFormHabanero form) { }

        #endregion

        #region Implementation of IBOColSelectorControl

        public IBusinessObject GetBusinessObjectAtRow(int row)
        {
            return null; 
        }

        public IBusinessObjectCollection BusinessObjectCollection
        {
            get { return null; }
            set { }
        }

        public IBusinessObject SelectedBusinessObject
        {
            get { return null; }
            set { }
        }

        public void Clear()
        {
        }

        public bool AutoSelectFirstItem
        {
            get { return false; }
            set { }
        }


        public int NoOfItems
        {
            get { return 0; }
        }

        #endregion


    }
}